Skip to content

fix(langgraph): carry ToolMessage.error onto the LangChain status flag - #2263

Merged
contextablemark merged 1 commit into
ag-ui-protocol:mainfrom
TheSeydiCharyyev:fix/2226-langgraph-toolmessage-error-status
Aug 3, 2026
Merged

fix(langgraph): carry ToolMessage.error onto the LangChain status flag#2263
contextablemark merged 1 commit into
ag-ui-protocol:mainfrom
TheSeydiCharyyev:fix/2226-langgraph-toolmessage-error-status

Conversation

@TheSeydiCharyyev

Copy link
Copy Markdown
Contributor

Fixes #2226.

Problem

Both langgraph adapters drop AG-UI's ToolMessage.error when they convert an incoming tool message to a LangChain ToolMessage. LangChain has a status field ("success" | "error") for exactly this, and providers such as langchain_anthropic map it onto the model's tool-result flag. With the field dropped, a client-reported tool failure reaches the model as a success. The impact is provider-dependent, so it is invisible on Gemini and shows up on Anthropic.

Fix

Map error onto status in both adapters: "error" when the AG-UI error field is set, else "success".

  • TypeScript — integrations/langgraph/typescript/src/utils.ts, the tool branch of aguiMessagesToLangChain. The langgraph-sdk ToolMessage type already types status?: "error" | "success".
  • Python — integrations/langgraph/python/ag_ui_langgraph/utils.py, the tool branch of agui_messages_to_langchain.

The AG-UI ToolMessage schema already has error in both languages, so no type changes are needed.

Scope

This PR maps the flag only. The two open questions from the issue — preserving the error text and round-tripping it back to the client — look like a separate protocol topic and are left out here.

Tests

A test is added on each side, next to the existing tool-message conversion tests.

  • TS: message-conversion.test.ts — full package suite green, 265 tests.
  • Python: test_message_conversion.pyunittest discover tests green, 43 tests.

Both langgraph adapters dropped AG-UI's ToolMessage.error when converting an incoming tool message to a LangChain ToolMessage. LangChain has a status field (success/error) for this, and providers such as langchain_anthropic map it onto the model's tool-result flag. With the field dropped, a client-reported tool failure reached the model as a success. The impact is provider-dependent, so it was invisible on Gemini.

Map error onto status in both adapters (TypeScript and Python): status is error when the AG-UI error field is set, else success. A test is added on each side.

Scope: the status flag only. Preserving the error text and round-tripping it back to the client are separate questions raised in the issue and left out here.

Fixes ag-ui-protocol#2226
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Python Preview Packages

Version 0.0.0.dev1785306123 published to TestPyPI.

Warning: These packages are built from contributor code that may not yet have been vetted for correctness or security. Install at your own risk and do not use in production.

Install with uv

Add the TestPyPI index to your pyproject.toml:

[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
explicit = true

Then install the packages you need:

# Core SDK
uv add 'ag-ui-protocol==0.0.0.dev1785306123' --index testpypi

# Integrations (each already depends on the matching ag-ui-protocol preview)
uv add 'ag-ui-langgraph==0.0.0.dev1785306123' --index testpypi
uv add 'ag-ui-crewai==0.0.0.dev1785306123' --index testpypi
# NOTE: ag-ui-agent-spec depends on pyagentspec (git-only, not on PyPI).
# You will need to install pyagentspec separately from its git repo.
uv add 'ag-ui-agent-spec==0.0.0.dev1785306123' --index testpypi
uv add 'ag_ui_adk==0.0.0.dev1785306123' --index testpypi
uv add 'ag_ui_strands==0.0.0.dev1785306123' --index testpypi

Install with pip

pip install \
  --index-url https://test.pypi.org/simple/ \
  --extra-index-url https://pypi.org/simple/ \
  ag-ui-protocol==0.0.0.dev1785306123

Use --extra-index-url https://pypi.org/simple/ so pip can resolve
transitive dependencies (pydantic, fastapi, etc.) from real PyPI.


Commit: e8a4ba0

@contextablemark

Copy link
Copy Markdown
Contributor

Reviewed and verified locally against the PR head.

  • Python: 384 tests pass (unittest discover tests).
  • TypeScript: 265 tests pass, tsc --noEmit clean.
  • The type claim checks out — @langchain/langgraph-sdk's types.messages.d.ts:105 declares status?: "error" | "success".
  • The TS path is genuinely end-to-end, not just cosmetic. The TS adapter ships a plain dict to the LangGraph server, and langchain_core's _create_message_from_message_type explicitly pops status out of additional_kwargs onto the real ToolMessage.status field for tool-role messages (verified on 1.2.25). On an older langchain_core it would degrade to additional_kwargs rather than break.

The fix is correct, minimal, and tested on both sides.

I've filed the two carve-outs so the scope of this PR is recorded and the remaining work isn't lost:

On the "should the error text travel too?" open question from #2226, which this PR sets aside — there's already an in-repo precedent that answers it, in case it's useful for the follow-ups: the claude-managed-agents adapters newline-join content + error into the tool result text and derive the provider's error flag from bool(error), on both sides (typescript/src/agent.ts:30-32, python/.../agent.py:521-532). Nothing to change here — the flag alone is the right minimum for this PR.

@pkg-pr-new

pkg-pr-new Bot commented Aug 3, 2026

Copy link
Copy Markdown

Open in StackBlitz

@ag-ui/a2a-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2a-middleware@2263

@ag-ui/a2ui-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2ui-middleware@2263

@ag-ui/event-throttle-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/event-throttle-middleware@2263

@ag-ui/mcp-apps-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mcp-apps-middleware@2263

@ag-ui/mcp-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mcp-middleware@2263

@ag-ui/a2a

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2a@2263

@ag-ui/adk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/adk@2263

@ag-ui/ag2

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/ag2@2263

@ag-ui/agno

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/agno@2263

@ag-ui/aws-strands

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/aws-strands@2263

@ag-ui/crewai

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/crewai@2263

@ag-ui/langchain

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/langchain@2263

@ag-ui/claude-agent-sdk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/claude-agent-sdk@2263

@ag-ui/langgraph

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/langgraph@2263

@ag-ui/llamaindex

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/llamaindex@2263

@ag-ui/mastra

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mastra@2263

@ag-ui/pydantic-ai

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/pydantic-ai@2263

@ag-ui/vercel-ai-sdk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/vercel-ai-sdk@2263

@ag-ui/watsonx

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/watsonx@2263

@ag-ui/a2ui-toolkit

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2ui-toolkit@2263

create-ag-ui-app

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/create-ag-ui-app@2263

@ag-ui/client

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/client@2263

@ag-ui/core

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/core@2263

@ag-ui/encoder

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/encoder@2263

@ag-ui/proto

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/proto@2263

commit: 3790517

@contextablemark contextablemark left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Created some follow-on issues.

@contextablemark
contextablemark merged commit 0880dff into ag-ui-protocol:main Aug 3, 2026
41 checks passed
BenTaylorDev pushed a commit that referenced this pull request Aug 10, 2026
….error

The reverse conversion (langchainMessagesToAgui / langchain_messages_to_agui) dropped the LangChain tool result status, so a status='error' tool message came back to the client with error unset. After #2263 fixed the forward direction, a client whose message list seeds the next run (fresh thread, stateless replay, snapshot-then-resend) re-converted with error unset and silently produced status='success' again, undoing the fix.

Map status == 'error' back onto AG-UI's error in both adapters. The forward direction is flag-only, so the original text is not recoverable here; error carries a fixed sentinel so a client can tell a reported failure apart from a reported failure text. Flag durable, text best-effort, per the standard agreed on #2306. A test is added on each side.

Fixes #2305
BenTaylorDev pushed a commit that referenced this pull request Aug 10, 2026
…in four more adapters

The same one-line omission fixed for LangGraph in #2263 is present in several other first-party adapters: AG-UI's ToolMessage.error is not read when an incoming tool result is converted into the target framework's tool-result shape, so a client-reported tool failure is handed to the model as a success.

Per the standard agreed on #2306, set the framework's error flag from bool(error) (flag only; text is not folded because every target here has a dedicated flag): langchain/typescript ToolMessage status (verbatim #2263); aws-strands/python Bedrock toolResult status (was pinned to success); vercel-ai-sdk/typescript AI SDK v4 tool-result isError; mastra/typescript AI SDK v4 tool-result isError.

Both vercel-ai-sdk and mastra resolve AI SDK v4, whose ToolResultPart already carries isError; no version gate is needed.

Also fix aws-strands _build_snapshot_messages, an AG-UI to AG-UI rebuild of the client's own messages: it dropped the client's error and encrypted_value on the snapshot echo. Copy both through.

A test is added next to each adapter's conversion tests.

Fixes #2306
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: LangGraph adapters drop ToolMessage.error, so a client-reported tool failure reaches the model as a success

2 participants